import React, {Component} from 'react';
import CanvasSVGForFac from "./canvasSVGForFac";
import {getTree} from "./fib";
import Menu from "./menu";
import Navbar from "./navbar";
import {MinHeap} from "./Heap";
import $ from "jquery"
import {r, randomList, range317, svgHeight, svgWidth, xBias, xBias2, xTimes, yBias, yTimes} from "./Const";
import CustomizedTables from "./table";
import CanvasSVGFor317 from "./canvasSVGFor317";


let tree;
let before = false;
let pause = false;

const generateN = (n) => {
    let list = [];
    for(let i = n; i >= 1; i--) {
        list.push(i);
    }

    return list;
}

const generateRes = (list, n) => {
    let temp = [];
    for (let i = 1; i <= n ; i ++) {
        if (i < list.length)
            temp.push(list[i]);
        else
            temp.push("");
    }
    return temp;
}

class IfElse extends Component {
    constructor() {
        super();
        this.state = {
            root:undefined,
            reset: false,
            vertices:[],
            edges:[],
            current:-1,
            n:0,
            r:2,
            // 这个flag 如果为0，那么就是普通的nr；如果为1，那么就是专门为判断树定制的n；如果为1那么就是什么都没有的
            nrFlag:true,
            redNumber: -1,
            algo:0,
            offset:0,
            time: 500,
            leftMost: undefined,
            rightMost: undefined,
            upMost: undefined,
            downMost: undefined,
            width: undefined,
            height: undefined,



            // 为3.17定制
            nowValue: undefined,

            // 随机选择的num
            selectNum: 0,
            // 最多可以选择到多少N
            MaxN: 20,

            select: false,

            setGreenFlag: false,

            // 以下是对阶乘而言
            // fac 的 N 和 Res
            listN : [],
            listRes : [],

            // 当前被选中 res idnex
            nowIndexRes: -1,
            nowIndexMul: -1,

            // 以下是对3.17而言
            // Sale
            listNSale: [],
            listResSale: [],
            nowIndexResSale: -1,
            nowIndexMulSale: -1,

            // Input

            listNInput: [],
            listResInput: [],
            nowIndexResInput: -1,
            nowIndexMulInput: -1,
            nowInputRes: undefined,

            // Output

            listNOutput: [],
            listResOutput: [],
            nowIndexResOutput: -1,
            nowIndexMulOutput: -1,
            nowOutputRes: undefined,
            typeOutput: "+",
            // N的符号
            nSymbol: "N"

        }
        this.input = [];
        this.inputKey = 0;
    }


    handlePaused = (flag) => {
        // this.setState({isPaused: flag});
        before = pause;
        pause = flag;
    }

    handleGenerate = () => {
        let inputElement;
        let algo = this.state.algo;
        if (algo === 1) {
            let maxN = this.state.MaxN;
            let choice = 0 | Math.random() * maxN;
            this.setState({selectNum: choice});

        } else {
            inputElement = $("#input");
            let [choice, list] = randomList(this.state.MaxN, range317);
            inputElement.val(list.reduce((a, b) => {return a + "," + b;}));
            this.setState({selectNum: choice});
        }
    }

    handleSpeed = (speed) => {
        let time;
        if (speed >= 50) {

            time = 900 - 9 * speed + 1;

        }
        else {
            time = 1800 - 8 * speed;
        }
        this.setState({time})
    }

    changeSelect = () => {
        let select = !this.state.select;
        this.setState({select});
    }

    realOnReset = () => {

        this.changeSelect();
        this.onReset();
    }

    onReset = () => {
        before = pause = false;
        this.setState({reset: true, setGreenFlag: false, vertices: [], edges: [], listN: [], listRes: [], nowIndexRes: -1, nowIndexMul: -1,
                    listNSale: [], listResSale: [], nowIndexResSale: -1, nowIndexMulSale: -1,
                    listNInput: [], listResInput: [], nowIndexResInput: -1, nowIndexMulInput: -1, nowInputRes: undefined,
                    listNOutput: [], listResOutput: [], nowIndexResOutput: -1, nowIndexMulOutput: -1, nowOutputRes: undefined,
        })
        // this.state.vertices = [];
        // this.state.edges = [];
        $("#img").css({
                        scale: "1",
                        transform: "scale(1)",
                        left: "0",
                        top: "10px",
                      })

    }

    // 执行去除tab和空格的操作
    clearPure = (string) => {
        let final = "";
        for (let i = 0; i < string.length; i++) {
            if (string[i] !== " " || string[i] !== "\t")
                final += string[i];
        }
        return final;
    }

    clearTabSpace = (string) => {
        let final = this.clearPure(string);
        return final.split(",").map((value) => parseInt(value));
    }

    sort = (string) => {
        return string.sort((a,b) => a-b);
    }

    handleInput = () => {
        try {
            let inputElement = document.getElementById("input");
            let input ;
            if (inputElement.value === "") {
                input = [];
            } else {
                input = this.clearTabSpace(inputElement.value);
            }
            // inputElement.value = input;
            this.input = [...input];
        } catch (e) {

        }

    }

    handleInputKey = () => {
        try {
            let inputKey = parseInt(this.clearPure(document.getElementById("input-key").value));
            this.inputKey = inputKey;
        } catch (e) {

        }

    }

    setAlgo = (pos, val) => {
        if (pos === 0) {
            this.setState({algo: val, nrFlag: val});
        }
    }

    setN = (pos, val) => {
        if (pos === 0) {
            this.setState({n: val});
        }
    }

    setR = (pos, val) => {
        if (pos === 0) {
            this.setState({r: val});
        }
    }
    addNumber = async ()=>{
        if (!before) {
            this.setState({redNumber: -1});

         this.onReset();

        if (this.state.reset) {
            this.onReset();
            await this.addNumberTemp();
        }
        await this.addNumberTemp();
        this.changeSelect();
        }
    }

    transForDraw = (tree, rootBias) => {
        tree.x = (tree.x - rootBias) * xTimes + (this.state.algo === 0 ? xBias2: xBias);
        tree.y = tree.y * yTimes + yBias;
        if (tree.left) {
            this.transForDraw(tree.left, rootBias);
        }
        if (tree.right) {
            this.transForDraw(tree.right, rootBias);
        }
    }

    transForLeftX = (tree, bias) => {
        tree.x += bias;
        if (tree.left) {
            this.transForLeftX(tree.left, bias);
        }
        if (tree.right) {
            this.transForLeftX(tree.right, bias);
        }
    }

    processTree = (tree) => {
        this.transForDraw(tree, tree.x);


        let leftMost = tree.getMostLeft(tree).x;
        if (leftMost - 2 * r < 0) {

            this.transForLeftX(tree, -leftMost + 2 * r);
        }

        leftMost = tree.getMostLeft(tree).x;

        let rightMost = tree.getMostRight(tree).x;
        let upMost = tree.y;
        let downMost = tree.getMostY(tree);
        let width = rightMost - leftMost + 4 * r;
        let height = downMost - upMost + 4 * r;

        width = width < 240 ? 240: width;
        height = height < 200 ? 200: height;

        this.setState({
            width,
            height
            });

        this.setState({edges:[],vertices:[], offset:tree.x, reset: false});
        this.state.vertices = [];
    }

    addNumberTemp = async () => {
            this.handleInput();
            this.handleInputKey();
            if (this.state.algo === 0 && this.input.length === 0) {
                return;
            }

            tree = getTree(this.state.n,this.state.algo,this.state.r, [...this.input], this.inputKey);
            this.processTree(tree);


            if (this.state.algo === 2) {
                     await this.recurHuffman(tree);
                } else if (this.state.algo === 0) {
                  await this.recurIfElse(tree);
                } else {
                    await this.recurFac(tree,this.state.n);
                }


            }

            cmp = (a, b, symbol) => {
                if (symbol === "<") {
                    return a < b;
                } else if (symbol === "≥") {
                    return a >= b;
                }
            }

    recurIfElseDraw = async (tree, node, key, symbol) => {
        if (!this.state.reset) {
            let tempLabel = node.tree.label;
            let startCut = 1;
            if (tempLabel[2] === "=") {
                startCut = 2
            }
            let nowCondition = parseInt(tempLabel.substring(startCut));

        // 处理本轮的情况
        // 先访问当前节点
        let vertices = this.state.vertices;
        let parent = node.parent;
        let current = vertices.length;
        if (!parent && node !== tree) {
            vertices.push({label: node.tree.label, val: node.tree.node, x:node.x,y:node.y,px:node.x,py:node.y});
            !this.state.reset && this.setState({vertices,current});
        }
        if (this.state.reset) return ;

        await sleep(this.state.time);
        let edges = this.state.edges;
        let nodeCurrent = current;

        if (this.state.reset) return ;
        for (let i = 0; i < 2; i++) {
            let child;
            let leftFlag = false;
            let stopFlag = true;
            if (i === 0 && node.left) {
                child = node.left;
                leftFlag = true;
                stopFlag = false;
            }

            if (i === 1 && node.right) {
                child = node.right;
                leftFlag = false;
                stopFlag = false;
            }

            if (stopFlag) continue;

            current = vertices.length;

            edges.push({
                x1:node.x,
                y1:node.y,
                x2:child.x,
                y2:child.y
            });
            if (this.state.reset) return ;
            !this.state.reset && this.setState({edges});

            vertices.push({label: child.tree.label, val: node.tree.node,
                x:child.x,y:child.y,px:node.x,py:node.y});
            !this.state.reset && this.setState({vertices, current});
            if (this.state.reset) return ;
            await sleep(this.state.time);
            if (leftFlag) {
                if (this.cmp(key, nowCondition, symbol)) {
                    return;
                }
                let redNumber = current ;
                if (this.state.reset) return ;
                !this.state.reset && this.setState({vertices, redNumber});
                await sleep(this.state.time);
                // 回到父节点
                current = nodeCurrent;
                if (this.state.reset) return ;
                !this.state.reset && this.setState({vertices, current});
            } else {
                if (!child.left && !child.right) {
                    return;
                }
                if (this.state.reset) return ;
                await this.recurIfElseDraw(tree, child, key, symbol);
            }

            }

        }
    }

    handleScroll = (tableId, index, i) => {
        let table = document.getElementById(tableId);
        let temp = document.getElementById(tableId + index.toString() + i.toString());
        table.scrollLeft = temp.offsetLeft - table.clientWidth + temp.clientWidth;
    }

    recurIfElse = async (node) => {
        try {

            let input = [...this.input];
            let vertex = {label: node.tree.label, val: node.tree.node, x:node.x,y:node.y,px:node.x,py:node.y};
            let tree = node;


            //nowIndexResSale: -1,
            //             nowIndexMulSale: -1,
            let n = input.length;
            let judgeSaleIndex = (key) => {
                if (key < 50) {
                    return 0;
                } else if (key < 100) {
                    return 1;
                } else if (key < 200) {
                    return 2;
                }
                return 3;
            }

            let generateN = (n, type) => {
                let list = [];
                for(let i = 0; i < n; i++) {
                    list.push(i);
                }
                if (type === "output") {
                    list.push("Sale2");
                    list.push("Final");
                }
                return list;
            }

            this.setState({
                listNSale: ["(0, 50)", "[50, 100)", "[100, 200)", "[200, +∞)"],
                listResSale: [0, 5, 15, 40],
                listNInput: generateN(n),
                listResInput: [],
                listNOutput: generateN(n, "output"),
                listResOutput: [0]
            });
            let listResInput = [];
            let listResOutput = [];


            this.setState({typeOutput: "+"})
            for(let i = 0 ; i < n; i++) {
                let key = input[i];
                !this.state.reset && await sleep(this.state.time);
                if (this.state.reset) return ;

                listResInput.push(key);
                !this.state.reset && this.setState({listResInput: [...listResInput], nowIndexResInput: i});
                await sleep(this.state.time);

                this.handleScroll("inputTable", 0, i);



                await sleep(this.state.time);

                !this.state.reset && this.setState({nowValue: key, vertices: [vertex], edges: [],current:0});
                !this.state.reset && await sleep(this.state.time);
                if (this.state.reset) return ;
                !this.state.reset && await this.recurIfElseDraw(tree, node, key, "<");
                !this.state.reset && await sleep(this.state.time * 2);

                if (this.state.reset) return ;
                let nowIndexResSale = judgeSaleIndex(key);
                !this.state.reset && this.setState({nowIndexResSale});
                 await sleep(this.state.time);


                if (this.state.reset) return ;
                !this.state.reset && this.setState({ nowInputRes: this.state.listResSale[nowIndexResSale]})
                 await sleep(this.state.time);
                !this.state.reset && this.setState({ nowIndexMulInput: i,})
                if (this.state.reset) return ;
                await sleep(this.state.time);
                listResInput[listResInput.length - 1] -= this.state.listResSale[nowIndexResSale];
                !this.state.reset && await sleep(this.state.time);
                // !this.state.reset && this.setState({listResInput});
                 await sleep(this.state.time);
                if (this.state.reset) return ;


                if (i !== 0) {
                    if (this.state.reset) return ;
                    !this.state.reset && this.setState({nowIndexMulOutput: i - 1, nowOutputRes: listResInput[listResInput.length - 1]});
                    !this.state.reset && await sleep(this.state.time);
                    listResOutput.push(listResInput[listResInput.length - 1] + listResOutput[i - 1]);
                }
                else {
                    if (this.state.reset) return ;
                    !this.state.reset && this.setState({nowIndexMulOutput: 0, nowOutputRes: listResInput[0]});
                    !this.state.reset && await sleep(this.state.time);
                    listResOutput.push(listResInput[listResInput.length - 1]);
                }

                if (this.state.reset) return ;
                !this.state.reset && await sleep(this.state.time);
                 if (this.state.reset) return ;
                // !this.state.reset && this.setState({ nowIndexResSale: -1, nowIndexMulInput:-1, nowIndexResInput: -1})
                !this.state.reset && this.setState({ nowIndexResSale: -1});



                !this.state.reset && await sleep(this.state.time);
                if (this.state.reset) return ;
                !this.state.reset && this.setState({listResOutput, nowIndexResOutput: i});
                !this.state.reset && await (this.state.time);
                this.handleScroll("outputTable", 0, i);
                !this.state.reset && await sleep(this.state.time);
                // !this.state.reset && this.setState({nowIndexMulOutput: -1});

            }
            !this.state.reset && await sleep(this.state.time);



            !this.state.reset && await sleep(this.state.time);
            {
                    // 最后的折扣
                    // [1000, +∞): 八折
                    // [500,1000): 九折
                    // (0,500): 无折扣



                    let finalSaleRange = ["(0,500)", "[500,1000)", "[1000, +∞)"];
                    let finalSale = ["No sale", "×0.9", "×0.8"];
                    this.setState({typeOutput: ""});
                    let translateFinalSale = [1, 0.9, 0.8];

                    let nowIndex = this.state.listResOutput.length - 1;
                    let finalTotal = this.state.listResOutput[nowIndex];
                    let nowIndexResSale;
                    if (finalTotal < 500) {
                        nowIndexResSale = 0;
                    } else if (finalTotal < 1000) {
                        nowIndexResSale = 1;
                    } else {
                        nowIndexResSale = 2;
                    }
                    this.setState({listNSale: finalSaleRange, listResSale: finalSale});
                   !this.state.reset && await sleep(this.state.time);

                {


                    let tree = getTree(this.state.n,4);
                    this.processTree(tree);
                    let vertex = {label: tree.tree.label, val: tree.tree.node, x:tree.x,y:tree.y,px:tree.x,py:tree.y};
                    !this.state.reset && this.setState({nowValue: finalTotal, vertices: [vertex], edges: [],current:0});
                    !this.state.reset && await sleep(this.state.time);

                    await this.recurIfElseDraw(tree, tree, finalTotal, "≥");
                    !this.state.reset && await sleep(this.state.time);
                }


                    !this.state.reset && this.setState({nowIndexResSale});
                    !this.state.reset && await sleep(this.state.time);
                    !this.state.reset && this.setState({nowIndexMulOutput: nowIndex, nowOutputRes: finalSale[nowIndexResSale]});
                    !this.state.reset && await sleep(this.state.time);


                    listResOutput.push((listResOutput[nowIndex] * translateFinalSale[nowIndexResSale]).toFixed(1));
                    nowIndex++;
                    this.setState({listResOutput, nowIndexResOutput: nowIndex})
                    !this.state.reset && await sleep(this.state.time);
                    this.handleScroll("outputTable", 0, nowIndex);

                    !this.state.reset && await sleep(this.state.time);
                    let afterInt = parseInt(listResOutput[nowIndex]);
                    let dValue = (listResOutput[nowIndex] - afterInt).toFixed(1);
                    this.setState({typeOutput: "-"})

                    !this.state.reset && this.setState({nowIndexMulOutput: nowIndex, nowOutputRes: dValue});
                    !this.state.reset && await sleep(this.state.time);
                    listResOutput.push(afterInt);
                    nowIndex++;
                    this.setState({listResOutput, nowIndexResOutput: nowIndex});
                    !this.state.reset && await sleep(this.state.time);
                    this.handleScroll("outputTable", 0, nowIndex);
                    // 抹零
                }

        } catch {}
    }

    // key 就是nowValue
    recurFacTree = async (node, key) => {
        try {
            if (!this.state.reset) {
                let tempLabel = node.tree.label;
            let startCut = 1;
            if (tempLabel[2] === "=") {
                startCut = 2
            }
            let nowCondition = parseInt(tempLabel.substring(startCut));

                let vertices = this.state.vertices;
                let current = vertices.length;
                await sleep(this.state.time);

                let edges = this.state.edges;
                let nodeCurrent = current;

                for (let i = 0; i < 2; i++) {
                    let child;
                    let leftFlag = false;
                    let stopFlag = true;
                    if (i === 0 && node.left) {
                        child = node.left;
                        leftFlag = true;
                        stopFlag = false;
                    }

                    if (i === 1 && node.right) {
                        child = node.right;
                        leftFlag = false;
                        stopFlag = false;
                    }

                    if (stopFlag) continue;

                    current = vertices.length;

                    edges.push({
                        x1:node.x,
                        y1:node.y,
                        x2:child.x,
                        y2:child.y
                    });

                    !this.state.reset && this.setState({edges});

                    vertices.push({label: child.tree.label, val: node.tree.node,
                        x:child.x,y:child.y,px:node.x,py:node.y});
                    !this.state.reset && this.setState({vertices, current});
                    await sleep(this.state.time);
                    if (leftFlag) {
                        if (key > nowCondition) {
                            return;
                        }
                        let redNumber = current ;
                        !this.state.reset && this.setState({vertices, redNumber});
                        await sleep(this.state.time);
                        // 回到父节点
                        current = nodeCurrent;
                        !this.state.reset && this.setState({vertices, current});
                    }

                    }

        }
        } catch (e) {

        }
    }


    // key 就是 n
    recurFac = async (node, key) => {
        // 处理本轮的情况
        // 先访问当前节点
        try {
            let n = key;
            let res = [1];
            let vertex = {label: node.tree.label, val: node.tree.node, x:node.x,y:node.y,px:node.x,py:node.y};
            this.setState({listN: generateN(n), listRes: generateRes(res, n),
            });
            // index 代表被选中的是哪个
            let index = 0;
            while (key >= 1) {

                !this.state.reset && this.setState({nowValue: key, vertices: [vertex], edges: [],current:0})
                if (this.state.reset)
                    return ;

                !this.state.reset && await sleep(this.state.time);
                !this.state.reset && await this.recurFacTree(node, key);

                if (index - 1 !== n - 3 && index - 1 !== n - 2) {
                     this.setState({nowIndexMul: index - 1 });
                     !this.state.reset && await sleep(this.state.time);
                } else {
                    !this.state.reset && this.setState({nowIndexMul: -1});
                }

                if (this.state.reset)
                    return ;

                !this.state.reset && await sleep(this.state.time );
                res.push(key * res[res.length - 1]);

                if (this.state.reset)
                    return ;

                !this.state.reset && this.setState({listRes: generateRes(res, n),nowIndexRes: index });
                !this.state.reset && await sleep(this.state.time );
                this.handleScroll("facTable", 0, index)
                if (this.state.reset)
                    return ;
                !this.state.reset && await sleep(this.state.time * 2);



                key --;
                index++;
        }
        } catch (e) {

        }

    }


    recur = async (node,parent)=>{
        try {
            let vertices = this.state.vertices;
        let current = this.state.vertices.length;

        if (!this.state.reset) {
             if( parent!==undefined ){

            if( node.left || node.right )
                vertices.push({label:node.tree.label,val:0,x:node.x,y:node.y,px:parent.x,py:parent.y});
            else
                vertices.push({label:node.tree.label,val:node.tree.node,x:node.x,y:node.y,px:parent.x,py:parent.y});
            !this.state.reset && this.setState({vertices,current});

            let edges = this.state.edges;
            edges.push({
                x1:parent.x,
                y1:parent.y,
                x2:node.x,
                y2:node.y
            });
            !this.state.reset && this.setState({edges});
        }else{
            if( node.left || node.right)
                vertices.push({label:node.tree.label,val:0,x:node.x,y:node.y,px:node.x,py:node.y});
            else
                vertices.push({label:node.tree.label,val:node.tree.node,x:node.x,y:node.y,px:node.x,py:node.y});
            !this.state.reset && this.setState({vertices,current});
        }
        await sleep(this.state.time);

        if (node.left) {
            !this.state.reset &&  await this.recur( node.left, node);
            !this.state.reset && this.setState({current});
            !this.state.reset && await sleep(this.state.time);
        }
        if (node.right) {
            !this.state.reset &&  await this.recur( node.right, node);
            !this.state.reset && this.setState({current});
            !this.state.reset && await sleep(this.state.time);
        }

        let verticess = [...this.state.vertices];
        verticess[current].val=node.tree.node;
        !this.state.reset && this.setState({vertices:verticess});

        }

        }
        catch (e) {
        }

    }

    algoVisualize = (algo) => {
          if (algo === 1) {
              return (
                  <React.Fragment>
                      <CanvasSVGForFac
                        nowValue = {this.state.nowValue}
                        width = {this.state.width}
                        height = {this.state.height}
                        flagForDraw = {this.state.flagForDraw}
                        setGreenFlag = {this.state.setGreenFlag}

                        algo = {this.state.algo}

                        time = {this.state.time}
                        N = {this.state.n}
                        vertices={this.state.vertices}
                        edges={this.state.edges}
                        current={this.state.current}
                        offset={this.state.offset}
                        reset = {this.state.reset}
                        nrFlag = {this.state.nrFlag}
                        redNumber = {this.state.redNumber}
                        nSymbol = {this.state.nSymbol}
                      />
                      <CustomizedTables
                          headName = "N"
                          bodyName = "Res"
                          tableId = "facTable"
                        listN = {this.state.listN}
                        listRes = {this.state.listRes}
                        nowIndexRes= {this.state.nowIndexRes}
                        nowIndexMul = {this.state.nowIndexMul}
                          type="×"
                      />
                  </React.Fragment>
              );
          }
          else if (algo === 0) {
              return (
                  <React.Fragment>
                      <div className="d-flex justify-content-center">
                          <div className="row row-cols-2 d-flex justify-content-center " style={{height: "calc(100vh - 140px)" , width: "100vw"}}>
                              <div className="col-5 h-50 d-flex justify-content-center align-items-center">
                                  <CanvasSVGFor317
                                    nowValue = {this.state.nowValue}
                                    width = {this.state.width}
                                    height = {this.state.height}
                                    flagForDraw = {this.state.flagForDraw}
                                    setGreenFlag = {this.state.setGreenFlag}

                                    algo = {this.state.algo}

                                    time = {this.state.time}
                                    N = {this.state.n}
                                    vertices={this.state.vertices}
                                    edges={this.state.edges}
                                    current={this.state.current}
                                    offset={this.state.offset}
                                    reset = {this.state.reset}
                                    nrFlag = {this.state.nrFlag}
                                    redNumber = {this.state.redNumber}
                                    nSymbol = {this.state.nSymbol}
                                    />
                              </div>
                              <div className="col-7 d-flex h-50 justify-content-center align-items-center">
                                  <CustomizedTables
                                      tableId = "inputTable"
                                      headName = "Index"
                                      bodyName = "Input"
                                      tableName = "Input table"
                                      nowRes = {this.state.nowInputRes}
                                    listN = {this.state.listNInput}
                                    listRes = {this.state.listResInput}
                                    nowIndexRes= {this.state.nowIndexResInput}
                                    nowIndexMul = {this.state.nowIndexMulInput}
                                      type= "-"
                                  />
                              </div>


                              <div className="col-5 d-flex h-50 justify-content-center align-items-center">
                                  <CustomizedTables
                                      headName = "Range"
                                      bodyName = "Sale"
                                      tableName = "Sale table"

                                    listN = {this.state.listNSale}
                                    listRes = {this.state.listResSale}
                                    nowIndexRes= {this.state.nowIndexResSale}
                                    nowIndexMul = {this.state.nowIndexMulSale}

                                  />
                              </div>
                              <div className="col-7 d-flex h-50 justify-content-center align-items-center">
                                  <CustomizedTables
                                      tableId = "outputTable"
                                      headName = "Index"
                                      bodyName = "Total"
                                      tableName = "Total table"
                                       nowRes = {this.state.nowOutputRes}
                                    listN = {this.state.listNOutput}
                                    listRes = {this.state.listResOutput}
                                    nowIndexRes= {this.state.nowIndexResOutput}
                                    nowIndexMul = {this.state.nowIndexMulOutput}
                                      type= {this.state.typeOutput}
                                  />

                              </div>
                          </div>

                    </div>
                  </React.Fragment>

              )
          }
    }

    render = () =>  {
        return (
            <div >
                <Navbar/>
                <Menu
                    handlePaused = {this.handlePaused}
                    select = {this.state.select}

                    MaxN = {this.state.MaxN}
                    selectNum = {this.state.selectNum}
                    onGenerate = {this.handleGenerate}
                    algo={this.state.algo}
                    handleSpeed = {this.handleSpeed}
                    setN={this.setN}
                    setR={this.setR}
                    setAlgo={this.setAlgo}
                    onStart={this.addNumber}
                    onReset={this.realOnReset}
                />
                {/*<Details*/}
                {/*    algo={this.state.algo}*/}
                {/*/>*/}
                {this.algoVisualize(this.state.algo)}
            </div>
        );
    }
}

// const requestAnimationFrame = window.requestAnimationFrame
// || window.mozRequestAnimationFram
// || window.webkitRequestAnimationFrame
// || window.msRequestAnimationFrame
// || function(callback){ window.setTimeout(callback, 1000/ 60)}

const cancelAnimationFrame = window.cancelAnimationFrame
|| window.mozCancelAnimationFrame;

function animateTimeout(cb,time){

	let i = 0;

    let myRef = null;
    let rememberTime = time;
	myRef = requestAnimationFrame(function fn(){
        if (pause)
            time = 100000000000;
        else
            time = rememberTime;
		if(i > Math.floor(60 / (1000/time)) ){
			cb();
			cancelAnimationFrame(myRef);
            // return ;
		}
		i++;

		myRef = requestAnimationFrame(fn)
	})
}


function sleep(ms) {
    return new Promise(resolve => animateTimeout(resolve, ms));
}
export default IfElse;